package com.zheng.oss.admin.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zheng.common.base.BaseController;
import com.zheng.common.util.Pagination;
import com.zheng.oss.common.constant.OssResult;
import com.zheng.oss.common.constant.OssResultConstant;
import com.zheng.oss.common.constant.enums.FilePermission;
import com.zheng.oss.dao.model.OssFile;
import com.zheng.oss.dto.FolderDto;
import com.zheng.oss.dto.ShareFileDto;
import com.zheng.oss.rpc.api.OssFileService;
import com.zheng.oss.rpc.api.OssFileStackService;
import com.zheng.upms.dao.model.UpmsUser;
import com.zheng.upms.rpc.api.UpmsApiService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by likun on 2018/4/29.
 */
@Controller
@Api(value = "个人文件管理", description = "个人文件管理")
@RequestMapping("/manage/oss/file/personal")
public class PersonalFileController extends BaseController {
    @Autowired
    private OssFileService fileService;
    @Autowired
    private UpmsApiService apiService;
    @Autowired
    private OssFileStackService fileStackService;
    private final int systemRootId = 1;
    private final int personalRootId = 2;

    @ApiOperation(value = "文档首页")
    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model) {
        model.addAttribute("folderId", personalRootId);
        model.addAttribute("folderType", OssFile.FOLDER_TYPE);
        return "/manage/personal/index.jsp";
    }

    @ApiOperation(value = "文件列表")
    @RequiresPermissions("oss:file:personal")
    @ResponseBody
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public Object list(@RequestParam(required = false, defaultValue = "1", value = "pageNumber") int pageNumber,
                       @RequestParam(required = false, defaultValue = "20", value = "pageSize") int pageSize,
                       @RequestParam(required = false, value = "sortName") String sortName,
                       @RequestParam(required = false, value = "sortOrder") String sortOrder,
                       OssFile file) {
        UpmsUser upmsUser = apiService.selectUpmsUserByUsername(getUsername());
        file.setPagination(new Pagination(pageNumber, pageSize, sortOrder, sortName));
        file.setStatus(OssFile.NORMAL_STATUS);
        file.setCuser(upmsUser.getUserId());
        if (file.getId() == null) {
            file.setId(personalRootId);
        }
        List<Map<String, Object>> rows = fileService.selectFilePage(file);
        Integer total = fileService.selectFilePageCount(file);
        Map<String, Object> result = new HashMap<>();
        result.put("rows", rows);
        result.put("total", total);
        return result;
    }

    @ApiOperation(value = "文件夹树")
    @RequiresPermissions("oss:file:personal")
    @ResponseBody
    @RequestMapping(value = "/folderList", method = RequestMethod.GET)
    public Object folderList(Integer checkedNodeId, Integer id) {
        UpmsUser upmsUser = apiService.selectUpmsUserByUsername(getUsername());
        EntityWrapper<OssFile> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("file_type", OssFile.FOLDER_TYPE)
                .eq("status", OssFile.NORMAL_STATUS)
                .eq("cuser", upmsUser.getUserId())
                .like("path", "," + personalRootId + ",");
        if (id == null) {
            entityWrapper.or("id=" + personalRootId);
        }
        List<OssFile> ossFiles = fileService.selectList(entityWrapper);
        JSONArray treeArray = new JSONArray();
        for (OssFile file : ossFiles) {
            JSONObject treeNode = new JSONObject();
            treeNode.put("id", file.getId());
            treeNode.put("pId", file.getPid());
            treeNode.put("name", file.getFilename());
            treeNode.put("open", true);
            if (checkedNodeId != null && checkedNodeId.equals(file.getId())) {
                treeNode.put("open", true);
            }
            treeArray.add(treeNode);
        }
        return treeArray;
    }

    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/update", method = RequestMethod.GET)
    public String update(Model model, Integer id) {
        OssFile file = fileService.selectById(id);
        model.addAttribute("file", file);
        model.addAttribute("folderPath", getFolderPath(file.getPid()) + file.getFilename());
        return "/manage/personal/update.jsp";
    }

    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Object update(OssFile file) {
        try {
            OssFile oldFile = fileService.selectById(file);
            EntityWrapper<OssFile> fileEntityWrapper = new EntityWrapper<>();
            fileEntityWrapper.eq("cuser", oldFile.getCuser()).eq("filename", file.getFilename());
            if (fileService.selectCount(fileEntityWrapper) > 1) {
                return new OssResult(OssResultConstant.FAILED, "当前目录下有相同名称的文件！");
            }
            fileService.updateById(file);
        } catch (Exception e) {
            return new OssResult(OssResultConstant.FAILED, null);
        }
        return new OssResult(OssResultConstant.SUCCESS, null);
    }

    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/upload", method = RequestMethod.GET)
    public String upload(Model model, Integer folderId) {
        //获取文件层级
        String folderPath = getFolderPath(folderId);
        //获取文件权限类型
        JSONArray filePermissions = FilePermission.getAll();
        model.addAttribute("folderId", folderId);
        model.addAttribute("folderPath", folderPath);
        model.addAttribute("filePermissions", filePermissions);
        return "/manage/personal/upload.jsp";
    }

    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/createFolder", method = RequestMethod.GET)
    public String createFolder(Model model, Integer folderId) {
        //获取文件层级
        String folderPath = getFolderPath(folderId);
        //获取文件权限类型
        JSONArray filePermissions = FilePermission.getAll();

        model.addAttribute("folderId", folderId);
        model.addAttribute("folderPath", folderPath);
        model.addAttribute("filePermissions", filePermissions);
        return "/manage/personal/createFolder.jsp";
    }

    private String getFolderPath(Integer pid) {
        StringBuilder sb = new StringBuilder("");
        OssFile pFile = fileService.selectById(pid);
        String[] ids = pFile.getPath().split(",");
        List<Integer> idList = new ArrayList<>();
        for (String idStr : ids) {
            idList.add(Integer.parseInt(idStr));
        }
        EntityWrapper<OssFile> fileEntityWrapper = new EntityWrapper<>();
        fileEntityWrapper.in("id", idList).or().eq("id", pid);
        List<OssFile> fileList = fileService.selectList(fileEntityWrapper);
        //判断第一个file的path中所含父id是否多于后一个file
       /* Collections.sort(fileList, (o1, o2) ->
                o1.getPath().split(",").length - o2.getPath().split(",").length);*/
        for (OssFile file : fileList) {
            sb.append(file.getFilename());
            sb.append("/");
        }
        return sb.toString();
    }

    @RequiresPermissions("oss:file:personal")
    @ResponseBody
    @RequestMapping(value = "/createFolder", method = RequestMethod.POST)
    public Object createFolder(@RequestBody FolderDto folder) {
        try {
            fileService.createFolder(folder, getUsername());
        } catch (Exception e) {
            return new OssResult(OssResultConstant.FAILED, e.getMessage());
        }
        return new OssResult(OssResultConstant.SUCCESS, null);
    }

    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/shareFile", method = RequestMethod.GET)
    public String shareFile(String fileIds, Model model) {
        model.addAttribute("fileIds", fileIds);
        return "/manage/personal/shareFile.jsp";
    }

    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/shareFile", method = RequestMethod.POST)
    @ResponseBody
    public Object shareFile(String fileIds, String userIds) {
        List<Integer> fileIdList = StringToIntegerList(fileIds, "-");
        List<Integer> userIdList = StringToIntegerList(userIds, ",");
        try {
            fileService.insertShare(userIdList, fileIdList);
        } catch (Exception e) {
            return new OssResult(OssResultConstant.FAILED, null);
        }
        return new OssResult(OssResultConstant.SUCCESS, null);
    }

    private static List<Integer> StringToIntegerList(String strArray, String split) {
        String[] array = strArray.split(split);
        List<Integer> integerList = new ArrayList<>();
        for (String str : array) {
            try {
                integerList.add(Integer.parseInt(str));
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return integerList;
    }

    @RequiresPermissions("oss:file:personal")
    @RequestMapping(value = "/viewShareFiles", method = RequestMethod.GET)
    public String viewShareFiles(Model model) {
        UpmsUser upmsUser = apiService.selectUpmsUserByUsername(getUsername());
        model.addAttribute("userId", upmsUser.getUserId());
        return "/manage/personal/viewShareFiles.jsp";
    }

    @ApiOperation(value = "文件列表")
    @RequiresPermissions("oss:file:personal")
    @ResponseBody
    @RequestMapping(value = "/shareFileList", method = RequestMethod.GET)
    public Object shareFileList(@RequestParam(required = false, defaultValue = "1", value = "pageNumber") int pageNumber,
                                @RequestParam(required = false, defaultValue = "20", value = "pageSize") int pageSize,
                                @RequestParam(required = false, value = "sortName") String sortName,
                                @RequestParam(required = false, value = "sortOrder") String sortOrder,
                                ShareFileDto shareFileDto) {
        shareFileDto.setPagination(new Pagination(pageNumber, pageSize, sortOrder, sortName));
        shareFileDto.setStatus(OssFile.NORMAL_STATUS);
        List<Map<String, Object>> rows = fileService.selectShareFilePage(shareFileDto);
        Integer total = fileService.selectShareFilePageCount(shareFileDto);
        Map<String, Object> result = new HashMap<>();
        result.put("rows", rows);
        result.put("total", total);
        return result;
    }
}
